header%20ipynb.png

Decision Tree Regression (DTR)


Decision Tree Regression (DTR) membangun model regresi dalam bentuk struktur pohon. DTR memecah dataset menjadi subset yang lebih kecil dan lebih kecil sementara pada saat yang sama pohon keputusan terkait dikembangkan secara bertahap. Hasil akhirnya adalah pohon dengan simpul keputusan dan simpul daun. Dengan titik data tertentu, DTR dijalankan sepenuhnya melalui seluruh pohon dengan menjawab pertanyaan Benar/Salah hingga mencapai simpul daun Prediksi terakhir adalah rata-rata dari nilai variabel dependen dalam simpul daun tertentu. Melalui beberapa iterasi, Pohon mampu memprediksi nilai yang tepat untuk titik data.

In [1]:
# Mengimpor libraries yang diperlukan

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import sklearn 

Pengunduhan Data


Untuk mengunduh data, gunakan !wget dengan URL yang diberikan.

In [2]:
#!wget -O FuelConsumption.csv https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/ML0101ENv3/labs/FuelConsumptionCo2.csv

FuelConsumptionCo2.csv:

Dataset FuelConsumptionCo2.csv yang diunduh mengandung model spesifik untuk rating konsumsi bahan bakar (fuel consumption) dan estimasi emisi karbon dioksida untuk kendaraan ringan yang dijual di Kanada. Dataset source

  • MODELYEAR e.g. 2014
  • MAKE e.g. Acura
  • MODEL e.g. ILX
  • VEHICLE CLASS e.g. SUV
  • ENGINE SIZE e.g. 4.7
  • CYLINDERS e.g 6
  • TRANSMISSION e.g. A6
  • FUEL CONSUMPTION in CITY(L/100 km) e.g. 9.9
  • FUEL CONSUMPTION in HWY (L/100 km) e.g. 8.9
  • FUEL CONSUMPTION COMB (L/100 km) e.g. 9.2
  • CO2 EMISSIONS (g/km) e.g. 182 --> low --> 0

Membaca Data


In [3]:
df = pd.read_csv("FuelConsumption.csv")

# melihat dataset
df.head()
Out[3]:
MODELYEAR MAKE MODEL VEHICLECLASS ENGINESIZE CYLINDERS TRANSMISSION FUELTYPE FUELCONSUMPTION_CITY FUELCONSUMPTION_HWY FUELCONSUMPTION_COMB FUELCONSUMPTION_COMB_MPG CO2EMISSIONS
0 2014 ACURA ILX COMPACT 2.0 4 AS5 Z 9.9 6.7 8.5 33 196
1 2014 ACURA ILX COMPACT 2.4 4 M6 Z 11.2 7.7 9.6 29 221
2 2014 ACURA ILX HYBRID COMPACT 1.5 4 AV7 Z 6.0 5.8 5.9 48 136
3 2014 ACURA MDX 4WD SUV - SMALL 3.5 6 AS6 Z 12.7 9.1 11.1 25 255
4 2014 ACURA RDX AWD SUV - SMALL 3.5 6 AS6 Z 12.1 8.7 10.6 27 244

Eksplorasi Data


In [4]:
# merangkum data
df.describe()
Out[4]:
MODELYEAR ENGINESIZE CYLINDERS FUELCONSUMPTION_CITY FUELCONSUMPTION_HWY FUELCONSUMPTION_COMB FUELCONSUMPTION_COMB_MPG CO2EMISSIONS
count 1067.0 1067.000000 1067.000000 1067.000000 1067.000000 1067.000000 1067.000000 1067.000000
mean 2014.0 3.346298 5.794752 13.296532 9.474602 11.580881 26.441425 256.228679
std 0.0 1.415895 1.797447 4.101253 2.794510 3.485595 7.468702 63.372304
min 2014.0 1.000000 3.000000 4.600000 4.900000 4.700000 11.000000 108.000000
25% 2014.0 2.000000 4.000000 10.250000 7.500000 9.000000 21.000000 207.000000
50% 2014.0 3.400000 6.000000 12.600000 8.800000 10.900000 26.000000 251.000000
75% 2014.0 4.300000 8.000000 15.550000 10.850000 13.350000 31.000000 294.000000
max 2014.0 8.400000 12.000000 30.200000 20.500000 25.800000 60.000000 488.000000

Beberapa fitur dapat dieksplorasi dengan cara berikut.

In [5]:
cdf = df[['ENGINESIZE','CYLINDERS','FUELCONSUMPTION_COMB','CO2EMISSIONS']]
cdf.head(10)
Out[5]:
ENGINESIZE CYLINDERS FUELCONSUMPTION_COMB CO2EMISSIONS
0 2.0 4 8.5 196
1 2.4 4 9.6 221
2 1.5 4 5.9 136
3 3.5 6 11.1 255
4 3.5 6 10.6 244
5 3.5 6 10.0 230
6 3.5 6 10.1 232
7 3.7 6 11.1 255
8 3.7 6 11.6 267
9 2.4 4 9.2 212

Fitur-fitur tersebut dapat diplot sebagai berikut:

In [6]:
viz = cdf[['CYLINDERS','ENGINESIZE','CO2EMISSIONS','FUELCONSUMPTION_COMB']]
viz.hist()
plt.show()

Plot fitur-fitur vs emisi dapat dibuat dan dapat dilihat linearitas hubungannya.

In [7]:
plt.scatter(cdf.FUELCONSUMPTION_COMB, cdf.CO2EMISSIONS,  color='blue')
plt.xlabel("FUELCONSUMPTION_COMB")
plt.ylabel("Emission")
plt.show()
In [8]:
plt.scatter(cdf.ENGINESIZE, cdf.CO2EMISSIONS,  color='blue')
plt.xlabel("Engine size")
plt.ylabel("Emission")
plt.show()
In [9]:
plt.scatter(cdf.CYLINDERS, cdf.CO2EMISSIONS,  color='blue')
plt.xlabel("Cylinders")
plt.ylabel("Emission")
plt.show()

Pembuatan dataset pelatihan dan pengujian

Pemisahan data latih/uji melibatkan pemisahan dataset menjadi dataset pelatihan dan pengujian, yang saling eksklusif. Setelah itu, dataset pelatihan dapat digunakan untuk membuat model dan dataset pengujian untuk pengujian. Hal ini akan memberikan evaluasi yang lebih akurat pada akurasi out-of-sample karena dataset pengujian bukan merupakan bagian dari dataset yang telah digunakan untuk melatih data. Ini lebih realistis untuk masalah dunia nyata.

Ini berarti bahwa hasil dari setiap titik data dalam kumpulan data ini diketahui, sehingga sangat bagus untuk data pengujian. Dataset pengujian belum digunakan untuk melatih model, sehingga model tidak memiliki pengetahuan tentang hasil dari data ini, sehingga dapat disebut pengujian di luar sampel.

In [10]:
# Mengambil "Engine Size" sebagai variabel independen (regressor)
X = cdf.iloc[:, 0].values
# Mengambil "Emission" sebagai variabel dependen
y = cdf.iloc[:, 3].values
# Reshape data karena hanya menggunakan satu fitur "Engine Size"
X = X.reshape(-1,1)
# Reshape data karena hanya satu fitur
y = y.reshape(-1,1)

Proses splitting dataset pelatihan dan pengujian

In [11]:
# Splitting the dataset into the Training set and Test set
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)

Normalisasi atau scaling dataset

In [12]:
# Feature Scaling
from sklearn.preprocessing import StandardScaler
sc_X = StandardScaler()
sc_y = StandardScaler()
X = sc_X.fit_transform(X)
y = sc_y.fit_transform(y)

Pembuatan Model

In [13]:
# Fitting Decision Tree Regression to the dataset
from sklearn.tree import DecisionTreeRegressor
regressor = DecisionTreeRegressor()
regressor.fit(X, y)
Out[13]:
DecisionTreeRegressor()

Prediksi nilai baru dengan model yang telah dibentuk

In [14]:
# Predicting a new result

y_pred = regressor.predict(sc_X.transform(np.array([[5.4]])))
#To transform 5.4 to the scaled X value, we first need to convert it into the array form
#Since the transform method of StandardScaler Library only accepts arrays

y_pred = sc_y.inverse_transform(y_pred)
#Now the prediction gives us the scaled value of y
#Thus we need inverse transformation of the scaled value for the real results

print(y_pred)
[373.375]

Visualisasi Hasil dalam nilai yang discaling:

In [15]:
# Visualising the Decision Tree Regression results (higher resolution)
X_grid = np.arange(min(X), max(X), 0.01)
X_grid = X_grid.reshape((len(X_grid), 1))
plt.scatter(X, y, color = 'blue')
plt.plot(X_grid, regressor.predict(X_grid), color = 'red')
plt.title('Emission Dataset')
plt.xlabel('Engine Size')
plt.ylabel('Emission')
plt.show()

Visualisasi Hasil dalam nilai asalnya:

In [16]:
# Visualising the Decision Tree Regression results (higher resolution)
X_grid = np.arange(min(X), max(X), 0.01)
X_grid = X_grid.reshape((len(X_grid), 1))
plt.scatter(sc_X.inverse_transform(X), sc_y.inverse_transform(y), color = 'blue')
plt.plot(sc_X.inverse_transform(X_grid), sc_y.inverse_transform(regressor.predict(X_grid)), color = 'red')
plt.title('Emission Dataset')
plt.xlabel('Engine Size')
plt.ylabel('Emission')
plt.show()

Visualisasi Tree (dengan nilai yang discaling):

In [17]:
import graphviz
from sklearn import tree

# DOT data
dot_data = tree.export_graphviz(regressor, out_file=None, feature_names=['Engine Size'],  
                                filled=True)

# Draw graph
graph = graphviz.Source(dot_data, format="png") 
graph
Out[17]:
Tree 0 Engine Size <= 0.391 mse = 1.0 samples = 1067 value = -0.0 1 Engine Size <= -0.527 mse = 0.399 samples = 767 value = -0.479 0->1 True 40 Engine Size <= 1.769 mse = 0.448 samples = 300 value = 1.225 0->40 False 2 Engine Size <= -1.022 mse = 0.216 samples = 429 value = -0.88 1->2 23 Engine Size <= 0.144 mse = 0.168 samples = 338 value = 0.029 1->23 3 Engine Size <= -1.411 mse = 0.112 samples = 152 value = -1.176 2->3 16 Engine Size <= -0.916 mse = 0.199 samples = 277 value = -0.717 2->16 4 Engine Size <= -1.481 mse = 0.012 samples = 8 value = -1.693 3->4 9 Engine Size <= -1.269 mse = 0.102 samples = 144 value = -1.147 3->9 5 Engine Size <= -1.587 mse = 0.012 samples = 7 value = -1.679 4->5 8 mse = 0.0 samples = 1 value = -1.788 4->8 6 mse = 0.001 samples = 3 value = -1.698 5->6 7 mse = 0.019 samples = 4 value = -1.665 5->7 10 Engine Size <= -1.34 mse = 0.098 samples = 42 value = -1.277 9->10 13 Engine Size <= -1.163 mse = 0.094 samples = 102 value = -1.094 9->13 11 mse = 0.064 samples = 30 value = -1.2 10->11 12 mse = 0.13 samples = 12 value = -1.471 10->12 14 mse = 0.061 samples = 65 value = -1.036 13->14 15 mse = 0.135 samples = 37 value = -1.196 13->15 17 mse = 0.188 samples = 158 value = -0.774 16->17 18 Engine Size <= -0.633 mse = 0.204 samples = 119 value = -0.642 16->18 19 Engine Size <= -0.775 mse = 0.136 samples = 63 value = -0.57 18->19 22 mse = 0.268 samples = 56 value = -0.722 18->22 20 mse = 0.081 samples = 2 value = -0.698 19->20 21 mse = 0.138 samples = 61 value = -0.566 19->21 24 Engine Size <= 0.003 mse = 0.191 samples = 195 value = -0.065 23->24 35 Engine Size <= 0.215 mse = 0.108 samples = 143 value = 0.158 23->35 25 Engine Size <= -0.351 mse = 0.166 samples = 100 value = 0.014 24->25 32 Engine Size <= 0.073 mse = 0.203 samples = 95 value = -0.148 24->32 26 mse = 0.095 samples = 11 value = -0.295 25->26 27 Engine Size <= -0.068 mse = 0.162 samples = 89 value = 0.052 25->27 28 Engine Size <= -0.174 mse = 0.171 samples = 84 value = 0.05 27->28 31 mse = 0.012 samples = 5 value = 0.088 27->31 29 mse = 0.184 samples = 75 value = 0.053 28->29 30 mse = 0.064 samples = 9 value = 0.026 28->30 33 mse = 0.018 samples = 12 value = -0.28 32->33 34 mse = 0.227 samples = 83 value = -0.129 32->34 36 mse = 0.105 samples = 92 value = 0.132 35->36 37 Engine Size <= 0.285 mse = 0.109 samples = 51 value = 0.205 35->37 38 mse = 0.08 samples = 35 value = 0.206 37->38 39 mse = 0.173 samples = 16 value = 0.203 37->39 41 Engine Size <= 1.239 mse = 0.359 samples = 233 value = 1.081 40->41 70 Engine Size <= 2.334 mse = 0.433 samples = 67 value = 1.729 40->70 42 Engine Size <= 0.815 mse = 0.293 samples = 134 value = 0.942 41->42 57 Engine Size <= 1.345 mse = 0.388 samples = 99 value = 1.268 41->57 43 Engine Size <= 0.533 mse = 0.214 samples = 58 value = 0.827 42->43 50 Engine Size <= 1.098 mse = 0.335 samples = 76 value = 1.03 42->50 44 mse = 0.065 samples = 22 value = 0.717 43->44 45 Engine Size <= 0.639 mse = 0.293 samples = 36 value = 0.895 43->45 46 mse = 0.44 samples = 6 value = 1.48 45->46 47 Engine Size <= 0.709 mse = 0.181 samples = 30 value = 0.777 45->47 48 mse = 0.202 samples = 10 value = 0.571 47->48 49 mse = 0.138 samples = 20 value = 0.88 47->49 51 Engine Size <= 0.992 mse = 0.516 samples = 37 value = 1.135 50->51 56 mse = 0.144 samples = 39 value = 0.93 50->56 52 Engine Size <= 0.921 mse = 0.362 samples = 27 value = 1.017 51->52 55 mse = 0.791 samples = 10 value = 1.454 51->55 53 mse = 0.283 samples = 10 value = 1.244 52->53 54 mse = 0.361 samples = 17 value = 0.884 52->54 58 mse = 0.157 samples = 6 value = 1.972 57->58 59 Engine Size <= 1.486 mse = 0.369 samples = 93 value = 1.223 57->59 60 Engine Size <= 1.416 mse = 0.353 samples = 56 value = 1.273 59->60 63 Engine Size <= 1.557 mse = 0.384 samples = 37 value = 1.147 59->63 61 mse = 0.323 samples = 48 value = 1.176 60->61 62 mse = 0.143 samples = 8 value = 1.849 60->62 64 mse = 0.518 samples = 14 value = 1.042 63->64 65 Engine Size <= 1.698 mse = 0.292 samples = 23 value = 1.211 63->65 66 Engine Size <= 1.628 mse = 0.295 samples = 22 value = 1.231 65->66 69 mse = 0.0 samples = 1 value = 0.754 65->69 67 mse = 0.443 samples = 6 value = 1.373 66->67 68 mse = 0.229 samples = 16 value = 1.178 66->68 71 Engine Size <= 1.946 mse = 0.381 samples = 59 value = 1.635 70->71 84 Engine Size <= 2.405 mse = 0.276 samples = 8 value = 2.418 70->84 72 Engine Size <= 1.84 mse = 0.278 samples = 17 value = 2.119 71->72 75 Engine Size <= 2.193 mse = 0.289 samples = 42 value = 1.439 71->75 73 mse = 0.0 samples = 3 value = 1.622 72->73 74 mse = 0.274 samples = 14 value = 2.226 72->74 76 Engine Size <= 2.122 mse = 0.274 samples = 38 value = 1.386 75->76 81 Engine Size <= 2.264 mse = 0.15 samples = 4 value = 1.938 75->81 77 Engine Size <= 2.052 mse = 0.291 samples = 33 value = 1.428 76->77 80 mse = 0.082 samples = 5 value = 1.114 76->80 78 mse = 0.298 samples = 32 value = 1.421 77->78 79 mse = -0.0 samples = 1 value = 1.654 77->79 82 mse = 0.0 samples = 1 value = 2.601 81->82 83 mse = 0.004 samples = 3 value = 1.717 81->83 85 mse = 0.0 samples = 4 value = 2.159 84->85 86 Engine Size <= 3.006 mse = 0.418 samples = 4 value = 2.676 84->86 87 mse = 0.162 samples = 2 value = 3.256 86->87 88 mse = -0.0 samples = 2 value = 2.096 86->88

Visualisasi Tree dalam file PNG

In [18]:
graph.render("decision_tree_graphivz")
'decision_tree_graphivz.png'
Out[18]:
'decision_tree_graphivz.png'

Evaluasi

Nilai aktual dan nilai prediksi dapat dibandingkan untuk menghitung akurasi dari model regresi. Metrik evaluasi sangat penting untuk pengembangan model karena memberikan pengetahuan untuk perbaikan model.

Ada berbagai metrik untuk evaluasi model, misalnya MSE sebagai error untuk mengetahui akurasi dari model yang dibangun yang dihitung dari MSE model terhadap data pengujian:

- Mean Absolute Error (MAE): Rerata dari nilai absolut dari error. MAE adalah metrik paling mudah dipahami karena hanya rata-rata dari error.
- Mean Squared Error (MSE): adalah rerata dari error dikuadratkan. MSE lebih populer dibanding MAE karena fokus pada error yang besar karena dikuadratkan sehingga berdampak lebih besar terhadap error yang lebih besar dibandingkan error yang lebih kecil.
- Root Mean Squared Error (RMSE).
- R-squared bukan error namun metrik yang populer yang merepresentasikan sejauh mana data cocok dengan garis regresi yang didapatkan. Semakin besar R-squared akan semaki baik pencocokan garis terhadap data. Nilai terbaik adalah 1.0 dan dapat bernilai negatif.
In [19]:
from sklearn.metrics import r2_score

test_x = np.asanyarray(cdf[['ENGINESIZE']])
test_y = np.asanyarray(cdf[['CO2EMISSIONS']])
test_y_ = sc_y.inverse_transform(regressor.predict(sc_X.transform(test_x)))

print("Mean absolute error: %.2f" % np.mean(np.absolute(test_y_ - test_y)))
print("Residual sum of squares (MSE): %.2f" % np.mean((test_y_ - test_y) ** 2))
print("R2-score: %.2f" % r2_score(test_y_ , test_y) )
Mean absolute error: 68.21
Residual sum of squares (MSE): 7301.88
R2-score: 0.78